

export class Tree {
    tree = [];
    list: any[] = [];
    map = {};
    opt: any = {};
    constructor(opt) {
        this.opt = Object.assign(
            {
                index: ['id', 'value', 'label', 'name'],
                item: null,
            },
            opt,
        );
    }

    load(arr) {
        if (!arr) return;
        this.list = [];
        this.map = {};
        this.tree = arr;

        this.parse(arr);
        this.createIndex();
    }

    createIndex() {
        this.list.forEach((t) => {
            this.opt.index.forEach((key) => {
                const index = t[key];
                if (!index) return;
                if (this.map[index]) {
                    console.log('tree index 冲突', index, this.map[index], t);
                } else {
                    this.map[index] = t;
                }
            });
        });
    }

    parse(arr, parent: any = null) {
        if (Array.isArray(arr)) {
            arr.forEach((item) => {
                this.parse(item, parent);
            });
        } else {
            arr['$_tree'] = {
                dir: 0,
                leaf: 0,
                total: 0,
            };
            arr['$_parent'] = parent;
            arr['$_leaf'] = !arr.children;
            this.opt.item?.(arr);
            this.list.push(arr);
            this.incCount(arr, arr['$_leaf']);

            if (Array.isArray(arr.children)) {
                this.parse(arr.children, arr);
            }
        }
    }

    incCount(item, leaf) {
        const parent = item['$_parent'];
        if (parent) {
            parent['$_tree'].total += 1;
            if (leaf) {
                parent['$_tree'].leaf += 1;
            } else {
                parent['$_tree'].dir += 1;
            }
            this.incCount(parent, leaf);
        }
    }

    get(key) {
        return this.map[key];
    }

    getNodes() {
        return this.list.filter((t) => t.$_leaf);
    }
}
